package org.lzuploader.controller;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/** Class used to convert data with md5 algorithm.
 * 
 * @author Emmanuel Cron
 *
 */
public final class Md5
{
    /** The logger for this class. */
    private static Log log = LogFactory.getLog(Md5.class);
    
    /** User should never instantiate this class. */
    private Md5()
    {
        throw new UnsupportedOperationException();
    }
    
    /** Converts a {@link String} into its md5 hash.
     * @param str Characters to convert
     * @return A 32 characters hash computed from the given string
     * @throws NoSuchAlgorithmException When the md5 algorithm is not found
     */
    public static String convert(final String str) throws NoSuchAlgorithmException
    {
        //log.debug("Converting following string to md5: " + str.toString());
        log.debug("Converting following string to md5: ********");
        log.trace("Fetching digest.");
        
        MessageDigest digest;
        try
        {
            digest = MessageDigest.getInstance("MD5");
        }
        catch (final NoSuchAlgorithmException nsae)
        {
            log.error("Couldn't find MD5 algorithm.");
            throw nsae;
        }
        
        log.trace("Updating digest with string.");
        
        final byte[] bytes = str.getBytes();
        digest.update(bytes, 0, bytes.length);
        
        log.trace("Computing digest and filling string with result.");
        
        final StringBuffer md5 = new StringBuffer();
        
        String appended;
        for (byte b : digest.digest())
        {
            appended = Integer.toString(b & 0x000000FF, 16);
            
            if (appended.length() < 2)
            {
                md5.append("0");
            }
            
            md5.append(appended);
            
        }
        
        log.trace("Calculated hash: " + md5.toString());
        
        return md5.toString();
    }
}
